<template>
  <div class="app-container">
    <el-form ref="queryForm" :model="queryParams" :inline="true">
      <el-form-item label="角色名称" prop="roleName">
        <el-input
          v-model="queryParams.roleName"
          size="small"
          style="width: 240px"
          placeholder="请输入角色名称"
        ></el-input>
      </el-form-item>
      <el-form-item label="权限字符" prop="roleSecurity">
        <el-input
          v-model="queryParams.roleSecurity"
          size="small"
          style="width: 240px"
          placeholder="请输入权限字符"
        ></el-input>
      </el-form-item>
      <el-form-item label="权限等级" prop="roleLevel">
        <el-select v-model="queryParams.roleLevel" placeholder="角色权限等级" size="small" style="width: 240px">
          <el-option
            v-for="item in 6"
            :key="item"
            :label="item - 1"
            :value="item - 1">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="创建时间">
        <el-date-picker
          v-model="dateRange"
          size="small"
          style="width: 240px"
          value-format="yyyy-MM-dd"
          type="daterange"
          range-separator="-"
          start-placeholder="开始日期"
          end-placeholder="结束日期">
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <div class="filter-container">
      <el-row :gutter="10">
        <el-col :span="1.5">
          <el-button type="primary" size="mini" plain icon="el-icon-plus" @click="handleAdd">
            新增
          </el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="success"
            size="mini"
            plain
            icon="el-icon-edit"
            :disabled="buttonState.editDisabled"
            @click="handleUpdate()"
          >
            修改
          </el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="danger"
            size="mini"
            plain
            icon="el-icon-delete"
            :disabled="buttonState.delDisabled"
            @click="handleDelete()"
          >
            删除
          </el-button>
        </el-col>
        <right-toolbar @queryTable="getData"></right-toolbar>
      </el-row>
    </div>
    <el-table :data="roleData" v-loading="loading" style="width: 100%" @selection-change="handleSelectionChange">
      <el-table-column
        type="selection"
        width="55"
        align="center"
      ></el-table-column>
      <el-table-column label="角色编号" prop="roleId" width="120"></el-table-column>
      <el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" />
      <el-table-column label="权限字符" prop="roleSecurity" :show-overflow-tooltip="true" width="150" />
      <el-table-column label="角色说明" prop="instruction" :show-overflow-tooltip="true" width="300" />
      <el-table-column label="权限等级" prop="roleLevel" width="100" />
      <el-table-column label="创建时间" prop="createdTime" width="180" align="center" />
      <el-table-column label="操作">
        <template slot-scope="scope" >
          <el-button type="primary" size="mini" :icon="scope.row.roleLevel != 0 ? 'el-icon-edit':'el-icon-view'" @click="handleUpdate(scope.row.roleId)">
            <span v-if="scope.row.roleLevel != 0">修改</span>
            <span v-else>查看</span>
          </el-button>
          <el-button size="mini" type="danger" icon="el-icon-delete" @click="handleDelete(scope.row.roleId)" v-if="scope.row.roleLevel != 0">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <Pagination
      v-show="totalCount>0"
      :total="totalCount"
      :page.sync="queryParams.page"
      :limit.sync="queryParams.limit"
      @pagination="getData"
    />

    <!-- 新增或修改角色对话框 -->
    <el-dialog
      :title="title"
      :visible.sync="open"
      width="500px">
      <el-form :model="form" ref="form" label-width="100px" :rules="rules">
        <el-form-item label="角色名称" prop="roleName">
          <el-input placeholder="请输入角色名称" v-model="form.roleName"></el-input>
        </el-form-item>
        <el-form-item prop="roleSecurity">
          <span slot="label">
            <el-tooltip content="角色的权限字符，判断是否有访问权限时使用，固定 ROLE_ 开头，文本框中输入权限即可，如：common" placement="top">
              <i class="el-icon-question"></i>
            </el-tooltip>
            权限字符
          </span>
          <el-input placeholder="请输入权限字符" v-model="form.roleSecurity">
            <template slot="prepend">ROLE_</template>
          </el-input>
        </el-form-item>
        <el-form-item prop="roleLevel">
          <span slot="label">
            <el-tooltip content="数字越小，权限越大，非超级管理员只能设置比自己权限小的等级" placement="top">
              <i class="el-icon-question"></i>
            </el-tooltip>
            权限等级
          </span>
          <el-input-number controls-position="right" v-if="form.roleLevel == 0" :min="0" :max="0" v-model="form.roleLevel" />
          <el-input-number controls-position="right" v-else :min="rolePreLevel+1" :max="5" v-model="form.roleLevel" />
        </el-form-item>
        <el-form-item label="菜单权限">
          <el-checkbox v-model="treeExpand" @change="setTreeExpand($event)">展开/折叠</el-checkbox>
          <el-checkbox v-model="treeCheckedAll" @change="setTreeCheckedAll($event)">全选/全不选</el-checkbox>
          <el-tree
            class="tree-border"
            show-checkbox
            empty-text="加载中，请稍候"
            :props="defaultProps"
            node-key="navId"
            ref="menu"
            :data="menuOptions"
          >
          </el-tree>
        </el-form-item>
        <el-form-item label="说明" prop="instruction">
          <el-input type="textarea" placeholder="请输入角色说明" v-model="form.instruction"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button type="primary" v-if="showSubmitBtn" @click="submitForm" :disabled="buttonState.submitDisabled">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { roleMenuTreeSelect } from '@/api/menu'
import { mapGetters } from 'vuex'
export default {
  name: 'Role',
  data() {
    let checkedRoleSecurityPrefix = (rule, value, callback) => {
      if (!value) {
        callback(new Error('权限字符不能为空'));
      } else {
        value = value.toLowerCase();
        if (value.startsWith(this.roleSecurityPrefix.toLowerCase())) {
          callback(new Error(`权限字符不要设置'${this.roleSecurityPrefix}'开头`));
        } else {
          callback();
        }
      }
    };
    return {
      buttonState: {
        editDisabled: true,
        delDisabled: true,
        submitDisabled: false
      },
      roleData: null,
      loading: false,
      queryParams: {
        page: 1,
        limit: 10,
        roleName: undefined,
        roleSecurity: undefined,
        roleLevel: undefined
      },
      // 日期范围
      dateRange: [],
      totalCount: 0,
      open: false,
      title: "",
      // 表单参数
      form: {},
      defaultProps: {
        children: "children",
        label: "label"
      },
      // 表单校验
      rules: {
        roleName: [
          { required: true, message: "角色名称不能为空", trigger: "blur" }
        ],
        roleSecurity: [
          { required: true, validator: checkedRoleSecurityPrefix, trigger: "blur" }
        ],
        roleLevel: [
          { required: true, message: "角色等级不能为空", trigger: "blur" }
        ]
      },
      // 菜单列表
      menuOptions: [],
      // 展开折叠
      treeExpand: false,
      // 全选、全不选
      treeCheckedAll: false,
      roleSecurityPrefix: "ROLE_",
      // 复选框选中的id
      ids: [],
      showSubmitBtn: true
    }
  },
  computed: {
    ...mapGetters([
      'rolePreLevel'
    ])
  },
  created() {
    this.getData();
  },
  methods: {
    // 删除角色
    handleDelete(roleId) {
      this.$confirm('此操作将永久删除角色是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let id = roleId || this.ids;
        this.deleteRequest(`/manage/role/${id}`).then(() => {
          // 判断删除之后页码数是否发生变化
          let totalPage = 0; 
          if (id instanceof Array) {
            // 批量删除
            totalPage = Math.ceil((this.totalCount - id.length) / this.queryParams.limit); // 剩余数据总页数
            this.totalCount -= id.length;
          } else {
            // 单条删除
            totalPage = Math.ceil((this.totalCount - 1) / this.queryParams.limit); // 剩余数据总页数
            this.totalCount -= 1;
          }

          this.queryParams.page = this.queryParams.page > totalPage ? totalPage : this.queryParams.page
          this.queryParams.page = this.queryParams.page < 1 ? 1 : this.queryParams.page

          this.getData()
        })
      }).catch(() => {});
    },
    // 选中复选框
    handleSelectionChange(val) {
      this.ids = val.map((item) => item.roleId);
      if (this.ids.length <= 0) {
        this.buttonState.delDisabled = true
      } else {
        this.buttonState.delDisabled = false
      }

      if (this.ids.length == 1) {
        this.buttonState.editDisabled = false
      } else {
        this.buttonState.editDisabled = true
      }
    },
    // 对话框表单提交
    submitForm() {
      this.$refs.form.validate(valid => {
        if (valid) {
          this.buttonState.submitDisabled = true;
          if (this.form.roleId != undefined) {
            // 修改
            let data = {...this.form};
            data.navIds = this.getMenuAllCheckedKeys();
            data.roleSecurity = this.roleSecurityPrefix + data.roleSecurity;
            this.putRequest('/manage/role/', data).then(resp => {
              this.open = false;
              this.getData();
              this.buttonState.submitDisabled = false;
            }).catch(() => {
              this.buttonState.submitDisabled = false;
            });
          } else {
            // 新增
            let insertData = {...this.form};
            insertData.navIds = this.getMenuAllCheckedKeys();
            insertData.roleSecurity = this.roleSecurityPrefix + insertData.roleSecurity;
            this.postRequest('/manage/role/', insertData).then(resp => {
              this.open = false;
              // 新增成功，跳转到最后一页
              this.totalCount += 1;
              let totalPage = Math.ceil(this.totalCount / this.queryParams.limit);
              this.queryParams.page = this.queryParams.page > totalPage ? this.queryParams.page : totalPage
              this.getData();
              this.buttonState.submitDisabled = false;
            }).catch(() => {
              this.buttonState.submitDisabled = false;
            });
          }
        }
      });
    },
    // 获取所有选中的菜单节点数据
    getMenuAllCheckedKeys() {
      // 被选中的菜单节点
      let checkedKeys = this.$refs.menu.getCheckedKeys();
      // 被半选中的菜单节点
      let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
      return checkedKeys;
    },
    // 全选、全不选
    setTreeCheckedAll(value) {
      this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
    },
    // 展开、折叠菜单列表
    setTreeExpand(value) {
      let treeList = this.menuOptions;
      for (let i = 0; i < treeList.length; i++) {
        this.$refs.menu.store.nodesMap[treeList[i].navId].expanded = value;
      }
    },
    getRoleMenuTreeSelect(roleId) {
      return roleMenuTreeSelect(roleId).then(resp => {
        this.menuOptions = resp.data.menus;
        return resp;
      })
    },
    // 打开新增对话框
    handleAdd() {
      this.getRequest('/manage/role/treeSelect').then(resp => {
        this.reset();
        this.menuOptions = resp.data;
        this.open = true;
        this.title = "新增角色";
      });
    },
    // 打开修改对话框
    handleUpdate(roleId) {
      this.reset();
      let id = roleId || this.ids[0];
      const roleMenu = this.getRoleMenuTreeSelect(id);
      this.getRequest(`/manage/role/${id}`).then(response => {
        this.form = response.data;
        if (response.data.roleLevel == 0) {
          this.showSubmitBtn = false;
        }
        this.$nextTick(() => {
          roleMenu.then(resp => {
            let checkedKeys = resp.data.checkedKeys;
            checkedKeys.forEach(key => {
              this.$nextTick(() => {
                this.$refs.menu.setChecked(key, true, false);
              })
            })
          });
          this.title = "修改角色";
          this.open = true;
        });
      })
    },
    reset() {
      if (this.$refs.menu != undefined) {
        this.$refs.menu.setCheckedKeys([]);
      }
      this.form = {
        roleId: undefined,
        roleName: undefined,
        roleSecurity: undefined,
        roleLevel: 5,
        navIds: [],
        instruction: undefined
      }
      this.treeExpand = false;
      this.treeCheckedAll = false;
      this.showSubmitBtn = true;
      this.resetForm('form');
    },
    // 弹出对话框取消按钮
    cancel() {
      this.open = false;
      setTimeout(() => {
        this.reset();
      }, 200)
    },
    // 重置搜索条件
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 搜索
    handleQuery() {
      this.queryParams.page = 1;
      this.getData();
    },
    getData() {
      this.loading = true;
      this.getRequest('/manage/role/list', this.addDateRange(this.queryParams, this.dateRange)).then(resp => {
        this.roleData = resp.data.list;
        this.loading = false;
        this.totalCount = Number(resp.data.total);
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  .filter-container {
    padding-top: 0;
  }

  .tree-border {
    margin-top: 5px;
    border: 1px solid #e5e6e7;
    border-radius: 4px;
  }
}
</style>
